<?php
/**
 * @author spenceryg
 * @date 2022/2/2
 * @time 6:40 下午
 * @focus love & life
 */

namespace app\admin\controller\sys;

use app\admin\controller\sys\model\AdminFileModel;
use app\admin\controller\sys\validate\AdminFileValidate;
use think\facade\Request;
use think\facade\View;

/**
 * 后台文件
 * Class AdminFile
 * @package app\admin\controller\sys
 */
class AdminFile extends \app\BaseController
{
    public $errorMsg;
    public $model;
    public $validate;

    public function __construct(\think\App $app)
    {
        parent::__construct($app);
        $this->model=new AdminFileModel();
        $this->validate=new AdminFileValidate();
    }

    /**
     * 列表
     * @return string|\think\response\Json
     */
    public function index()
    {
        $listtype=input("listtype") ? input("listtype") : "img";
        if (!Request::param("pubid")) {
            return error("缺少pubid");
        }
        View::assign([
            "pubid"=>Request::param("pubid"),
            "listtype"=>$listtype,
            "file_checkbox"=>Request::param("file_checkbox"),
        ]);
        return View::fetch(app()->getAppPath() . 'controller/sys/view/admin_file/index.html');
    }

    /**
     * 列表模板
     * @return string
     */
    public function listtemp()
    {
        $listtype=Request::param("listtype");
        if ($listtype=="file") {
            return View::fetch(app()->getAppPath() . 'controller/sys/view/admin_file/'."file_temp.html");
        } elseif ($listtype=="video") {
            return View::fetch(app()->getAppPath() . 'controller/sys/view/admin_file/'."video_temp.html");
        } else {
            return View::fetch(app()->getAppPath() . 'controller/sys/view/admin_file/'."img_temp.html");
        }
    }
    //检测文件上传限制
    private function checkMaxSize()
    {
        return true;
        //这步判断其实用不上，分片上传就是为了跳过php.ini的限制的
        $listtype=Request::param("listtype") ? Request::param("listtype") : "img";
        //检测文件上传限制
        $iniMaxSize=ini_get('upload_max_filesize');
        $iniMaxSize=intval($iniMaxSize);
        $systemMaxSize=config('upload_'.$listtype.'.maxSize');
        $this->errorMsg="服务器设置最大上传文件为{$iniMaxSize}M，小于您后台[网站设置]的{$systemMaxSize}M,请修改php.ini的upload_max_filesize值";
        return $iniMaxSize>$systemMaxSize;
    }

    /**
     * 类型列表
     * @return string
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getlist()
    {
        $listtype=Request::param("listtype");
        $id=Request::param("id", 0, "int");
        $listRows=100;//每页显示多少条
        $where=array();
        //搜索
        $keywords=Request::param("keywords");
        if ($keywords) {
            $where[]=['name','LIKE','%'.$keywords.'%'];
        }

        //文件类型
        $exts=config("upload_".$listtype.'.exts');
        //指定pubid
        $pubid=Request::param("pubid");
        if ($pubid) {
            $where[]=['pubid','=',$pubid];
        }
        //id(当文件上传结束后增加一个单位)
        if ($id) {
            $where[]=['id','=',$id];
        }
        $exts_arr=explode(",", $exts);
        $where[]=['ext','in',$exts_arr];

        $page=Request::param("page", 0, "intval")-1;
        $page=$page<0 ? 0 : $page;

        $total=$this->model->where($where)->count();
        $start_row=$page*$listRows;
        $end_row=($page+1)*$listRows;

        $data=$this->model->where($where)->order("create_time desc")->limit($start_row, $end_row)->select();
        $rs=array();
        foreach ($data as $v) {
            $v['size']=$this->getsize($v['size']);
            $rs[]=$v;
        }

        View::assign("data", $rs);
        if ($listtype=="file") {
            return View::fetch(app()->getAppPath() . 'controller/sys/view/admin_file/'."file_li.html");
        } elseif ($listtype=="video") {
            return View::fetch(app()->getAppPath() . 'controller/sys/view/admin_file/'."video_li.html");
        } else {
            return View::fetch(app()->getAppPath() . 'controller/sys/view/admin_file/'."img_li.html");
        }
    }

    //文件大小
    private function getsize($size)
    {
        $units = array(' B', ' KB', ' MB', ' GB', ' TB');
        for ($i = 0; $size >= 1024 && $i < 4; $i++) {
            $size /= 1024;
        }
        return round($size, 2).$units[$i];
    }

    /**
     * 文件上传
     * @return \think\response\Json
     */
    public function add()
    {
        //检测文件上传限制
        if (!$this->checkMaxSize()) {
            return error($this->errorMsg);
        }
        $config=[];
        $config['pubid']=input("get.pubid", 0, "intval");
        $config['listtype']=input("get.listtype");
        $config['chunks']=input("post.chunks", 0, "intval");//chunks如果大于1为大文件分片上传
        $config['chunk']=input("post.chunk", 0, "intval");//如果开启了分处，则当前是第几个分片
        $uploadSet=config("upload_".$config['listtype']);
        //常规文件上传
        if (!$config['chunks']) {
            $file = request()->file();
            //文件验证
            $this->validate->rule['file']['fileExt']=$uploadSet['exts'];
            $this->validate->rule['file']['fileSize']=$uploadSet['maxSize']*1024*1024;
            if (!$this->validate->check($file)) {
                return error($this->validate->getError());
            }
            //保存文件
            $data=$this->model->saveFile($config, $file['file']);
            return success("上传成功", $data["filepath"]);
        }
        //大文件分片上传
        else {
            $this->model->chunks=$config['chunks'];
            $this->model->chunk=$config['chunk'];
            //设定缓存文件夹名称
            $this->model->chunks_cache_path="./upload/cache/chunks_file_cahce/".$this->user_id."-".md5($_FILES['file']["name"])."/";
            //第一个分片要创建目录
            if ($config['chunk']==0) {
                $this->model->makeTempPath();
            }
            //保存分片
            $this->model->saveCacheFile();
            //如果是最后一个文件
            if (($config['chunks']-1)==$config['chunk']) {
                //将所有分片合并为一个文件
                $mergeTmp=$this->model->mergeFile();
                $_FILES['file']["tmp_name"]=$mergeTmp;
                $_FILES['file']["size"]=  filesize($mergeTmp);
                //强行对request里注入合并后的缓存文件
                request()->withFiles($_FILES);
                $file = request()->file();
                //文件验证
                $this->validate->rule['file']['fileExt']=$uploadSet['exts'];
                $this->validate->rule['file']['fileSize']=$uploadSet['maxSize']*1024*1024;
                if (!$this->validate->check($file)) {
                    return error($this->validate->getError());
                }
                //保存文件
                $data=$this->model->saveFile($config, $file['file']);
                //删除分片缓存目录
                $this->model->del_dir($this->model->chunks_cache_path);
                //日志
                return success("上传成功", $data["filepath"]);
            } else {
                return success("分片上传成功");
            }
        }
    }

    /**
     * 删除
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function delete()
    {
        $ids=Request::param("ids");
        $ids_arr=explode(",", $ids);
        if (count($ids_arr)>0) {
            foreach ($ids_arr as $id) {
                $id=(int)$id;
                //根据id查找文件路径
                $filers=$this->model->find($id);

                if ($filers["filepath"]) {
                    unlink(".".$filers["filepath"]);//删除文件
                }
                //缩略图
                if ($filers["smallpath"]) {
                    unlink(".".$filers["smallpath"]);//删除文件
                }
                //
                $this->model->where("id", $filers["id"])->delete($id);
            }
        }
        return success("删除成功");
    }


    /**
     * 获取文件上传限制
     * @return \think\response\Json
     */
    public function uploadConfig()
    {
        $data=[
            "img"=>["title"=>"Images","extensions"=>config('upload_img.exts'),"mimeTypes"=>config('upload_img.mimes'),"maxSize"=>config('upload_img.maxSize')],
            "file"=>["title"=>"Images","extensions"=>config('upload_file.exts'),"mimeTypes"=>config('upload_file.mimes'),"maxSize"=>config('upload_file.maxSize')],
            "video"=>["title"=>"Images","extensions"=>config('upload_video.exts'),"mimeTypes"=>config('upload_video.mimes'),"maxSize"=>config('upload_video.maxSize')],
        ];
        return success('', $data);
    }


    /**
     * 下载文件
     * @param $id
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function download($id)
    {
        $file=$this->model->find($id);
        $filePath=".".$file->filepath;
        if (!is_file($filePath)) {
            parent::error('文件不存在');
        } else {
            //文件大小不做限制
            ini_set('memory_limit', '2568888M'); //升级为256M内存
            header("Content-type:application/octet-stream");
            header("Content-Disposition:attachment;filename = " . basename($file['name']));
            header("Accept-ranges:bytes");
            header("Accept-length:" . filesize($filePath));
            $handle = fopen($filePath, 'rb');
            echo fread($handle, filesize($filePath));
            fclose($handle);
            exit();
        }
    }


    /**
     * 针对百度截图过来的文件上传
     */
    public function ueditorImg()
    {
        $action=Request::param("action");
        //请示配置
        if ($action=="config") {
            foreach (explode(",", config('upload_img.exts')) as $v) {
                $ext_arr[]=".".$v;
            }
            $config=[
                "imageActionName"=>"uploadimage",
                "imageAllowFiles"=>$ext_arr,
                "imageCompressBorder"=>"1600",
                "imageCompressEnable"=>true,
                "imageFieldName"=>"file",
                "imageInsertAlign"=>"none",
                "imageMaxSize"=>config('upload_img.maxSize')*1024*1024,
                "imagePathFormat"=>"/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}",
                "imageUrlPrefix"=>"",
            ];
            echo json_encode($config);
            exit;
        }
        //上传文件
        elseif ($action=="uploadimage") {
            $config=[];
            $config['pubid']=Request::param("pubid", 0, "intval");
            $config['listtype']="img";
            $config['chunks']=0;//chunks如果大于1为大文件分片上传
            $config['chunk']=0;//如果开启了分处，则当前是第几个分片

            $file = request()->file();
            $data=$this->model->saveFile($config, $file['file'], "截图-".date("YmdHis"));
            $result=[
                "original"=>$data['name'],
                "size"=>$data['size'],
                "state"=>"SUCCESS",
                "title"=>$data['name'],
                "type"=>".".$data['ext'],
                "url"=>$data['filepath'],
            ];
            echo json_encode($result);
            exit;
        }
    }
}
